/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package monitoring.general;

import org.postgis.Point;
import java.io.IOException;
import java.io.Serializable;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.el.ELContext;
import javax.faces.bean.ManagedBean;
import javax.faces.context.FacesContext;
import javax.faces.event.AjaxBehaviorEvent;
import org.primefaces.model.map.DefaultMapModel;
import org.primefaces.model.map.LatLng;
import org.primefaces.model.map.MapModel;
import org.primefaces.model.map.Marker;
import system.general.Exc;
import system.general.Logged;
import system.general.Message;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Enumeration;
import java.util.Properties;
import javax.faces.bean.ViewScoped;
import javax.faces.model.SelectItem;
import org.primefaces.context.RequestContext;
import org.primefaces.event.map.OverlaySelectEvent;
import org.primefaces.model.map.Polyline;

/**
 *
 * @author jarosemena
 */
@ManagedBean(name = "monitoring_general")
@ViewScoped
public class Main extends Beans implements Serializable {
    //Variables de importación General

    Logged logged;
    private Message msg = new Message();
    //Variables de importación otros modulos
    private gps.general.Find gpsFind = new gps.general.Find();
    private user.allocation.Find userAllocationFind = new user.allocation.Find();
    //Variables del modulo
    private Find gps_weaveFind;
    private List<Beans> gps_weaveList = new ArrayList<>();
    private List<Beans> navigationHistoryList = new ArrayList<>();
    private List<Beans> filteredHistory = new ArrayList<>();
    private Date fecha_inicial = new Date();
    private Date fecha_final = new Date();
    private Double lat = 8.994957;
    private Double lng = -79.520531;
    private MapModel emptyModel;
    private MapModel mapModel;
    private List<gps.general.Beans> gpsList = new ArrayList<>();
    private List<user.allocation.Beans> userAllocationList = new ArrayList<>();
    //Variables locales
    private Map<String, String> map = new LinkedHashMap<>();
    private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private Boolean toggled = false;
    private Date lifetrackStartDate;
    private Marker marker;

    public Main() {
        ELContext elContext = FacesContext.getCurrentInstance().getELContext();
        logged = (Logged) FacesContext.getCurrentInstance().getApplication().getELResolver().getValue(elContext, null, "logged");
        emptyModel = new DefaultMapModel();
        mapModel = new DefaultMapModel();
    }

    public void load() {
        try {

            if (logged.getMasterId() != 0) {
                map.clear();
                map.put("g.id=" + logged.getMasterId(), " ");

                gpsList.clear();
                gpsList = gpsFind.byMap(map);

                setImei(gpsList.get(0).getImei());
                getGpsBeans().setId(gpsList.get(0).getId());
                getGpsBeans().setImei(gpsList.get(0).getImei());
                getGpsBeans().setMarca(gpsList.get(0).getMarca());
                getGpsBeans().setModelo(gpsList.get(0).getModelo());
                getGpsBeans().setNombre(gpsList.get(0).getNombre());
                getGpsBeans().setNumero_serie(gpsList.get(0).getNumero_serie());
                getGpsBeans().setTipo(gpsList.get(0).getTipo());
                getGpsBeans().setCaducidad(gpsList.get(0).getCaducidad());
                getGpsBeans().setDetalle(gpsList.get(0).getDetalle());

                map.clear();
                map.put("ug.id_gps=" + getGpsBeans().getId(), " ");
                userAllocationList.clear();
                userAllocationList = userAllocationFind.byMap(map);

                for (user.allocation.Beans temp : userAllocationList) {
                    getUserBeans().setNombre(getUserBeans().getNombre() + " " + temp.getUser_loginBeans().getNombre() + " " + temp.getUser_loginBeans().getApellido() + ". ");
                }
                fillNavigationHistoryList();
            }
        } catch (Exc ex) {
            msg.showMsg(namePackage(), "system", ex.getIdError());
        } catch (SQLException ex) {
            msg.showErr(namePackage(), "sql", ex);
        } catch (Exception ex) {
            msg.showErr(namePackage(), "java", ex);
        } finally {
        }
    }

    public void drawByDateRange(AjaxBehaviorEvent event) {
        try {
            map.clear();
            map.put("imei='" + getImei() + "'", " LIMIT 1 ");
            LatLng coord = new LatLng(0, 0);
            Point p = new Point();
            Polyline polyline = new Polyline();
            gps_weaveFind = new Find();

            if (toggled) {
                throw new Exc("m21");
            }

            if (logged.getMasterId() != 0 && gps_weaveFind.byExist(map)) {
                map.clear();
                map.put("imei='" + getImei(), "' AND ");
                map.put("fecha::TIMESTAMP BETWEEN '" + format.format(fecha_inicial) + "'::TIMESTAMP AND '" + format.format(fecha_final) + "'::TIMESTAMP", " ORDER BY gt.id, gt.fecha ASC ");

                gps_weaveList = gps_weaveFind.byMap(map);
                if (!gps_weaveList.isEmpty()) {
                    polyline.setStrokeWeight(6);
                    polyline.setStrokeColor("#FF9900");
                    polyline.setStrokeOpacity(0.7);

                    for (Beans temp : gps_weaveList) {
                        p = new Point(temp.getCoordenadas().getValue());
                        coord = new LatLng(p.x, p.y);
                        polyline.getPaths().add(coord);
                        setLat(p.x);
                        setLng(p.y);
                    }
                    clearMapModel();
                    getMapModel().addOverlay(polyline);
                    getMapModel().addOverlay(new Marker(coord,
                            format.format(gps_weaveList.get(gps_weaveList.size() - 1).getFecha()),
                            p.x + " " + p.y,
                            "/gpstraces/faces/javax.faces.resource/image/map/icon-ui-car.png?ln=default"));
                }
            }

        } catch (Exc ex) {
            msg.showMsg(namePackage(), "system", ex.getIdError());
        } catch (SQLException ex) {
            msg.showErr(namePackage(), "sql", ex);
        } catch (Exception ex) {
            msg.showErr(namePackage(), "java", ex);
        } finally {
        }
    }

    public void drawByCurrentPosition(AjaxBehaviorEvent event) {
        try {
            map.clear();
            map.put("imei='" + getImei() + "'", " LIMIT 1 ");
            LatLng coord = new LatLng(0, 0);
            Point p;
            gps_weaveFind = new Find();

            if (toggled) {
                throw new Exc("m21");
            }

            if (logged.getMasterId() != 0 && gps_weaveFind.byExist(map)) {
                map.clear();
                map.put("imei='" + getImei(), "' ORDER BY gt.fecha DESC LIMIT 1 ");

                gps_weaveList = gps_weaveFind.byMap(map);
                if (!gps_weaveList.isEmpty()) {
                    p = new Point(gps_weaveList.get(0).getCoordenadas().getValue());
                    coord = new LatLng(p.x, p.y);
                    setLat(p.x);
                    setLng(p.y);
                    clearMapModel();
                    getMapModel().addOverlay(new Marker(coord,
                            format.format(gps_weaveList.get(0).getFecha()),
                            p.x + " " + p.y,
                            "/gpstraces/faces/javax.faces.resource/image/map/icon-ui-car.png?ln=default"));
                }
            }
        } catch (Exc ex) {
            msg.showMsg(namePackage(), "system", ex.getIdError());
        } catch (SQLException ex) {
            msg.showErr(namePackage(), "sql", ex);
        } catch (Exception ex) {
            msg.showErr(namePackage(), "java", ex);
        } finally {
        }
    }

    public void drawByLifeTrace() {
        try {
            map.clear();
            map.put("imei='" + getImei() + "'", " LIMIT 1 ");
            LatLng coord = new LatLng(0, 0);
            Point p = new Point();
            Polyline polyline = new Polyline();
            gps_weaveFind = new Find();

            if (logged.getMasterId() != 0 && gps_weaveFind.byExist(map)) {
                map.clear();
                map.put("imei='" + getImei(), "' AND ");
                map.put("fecha::TIMESTAMP BETWEEN '" + format.format(lifetrackStartDate) + "'::TIMESTAMP AND '" + format.format(new Date()) + "'::TIMESTAMP", " ORDER BY gt.id, gt.fecha ASC ");

                gps_weaveList = gps_weaveFind.byMap(map);
                if (!gps_weaveList.isEmpty()) {
                    polyline.setStrokeWeight(6);
                    polyline.setStrokeColor("#FF9900");
                    polyline.setStrokeOpacity(0.7);

                    for (Beans temp : gps_weaveList) {
                        p = new Point(temp.getCoordenadas().getValue());
                        coord = new LatLng(p.x, p.y);
                        polyline.getPaths().add(coord);
                        setLat(p.x);
                        setLng(p.y);
                    }
                    clearMapModel();
                    getMapModel().addOverlay(polyline);
                    getMapModel().addOverlay(new Marker(coord,
                            format.format(gps_weaveList.get(gps_weaveList.size() - 1).getFecha()),
                            p.x + " " + p.y,
                            "/gpstraces/faces/javax.faces.resource/image/map/icon-ui-car.png?ln=default"));
                }
            }

        } catch (Exc ex) {
            msg.showMsg(namePackage(), "system", ex.getIdError());
        } catch (SQLException ex) {
            msg.showErr(namePackage(), "sql", ex);
        } catch (Exception ex) {
            msg.showErr(namePackage(), "java", ex);
        } finally {
        }
    }

    public void drawByHistoryDate(Beans selectedRow) {
        LatLng coord;
        Point p;
        Marker m;

        try {
            if (!toggled) {
                p = new Point(selectedRow.getCoordenadas().getValue());
                coord = new LatLng(p.x, p.y);
                m = new Marker(coord,
                        format.format(selectedRow.getFecha()),
                        selectedRow.getCoordenadas().getGeometry().getPoint(0).x + " " + selectedRow.getCoordenadas().getGeometry().getPoint(0).y);
                setLat(p.x);
                setLng(p.y);
                if (!containsMarker(m)) {
                    getMapModel().addOverlay(m);
                }
            } else {
                throw new Exc("m21");
            }
        } catch (Exc ex) {
            msg.showMsg(namePackage(), "system", ex.getIdError());
        } catch (SQLException ex) {
            msg.showErr(namePackage(), "sql", ex);
        } catch (Exception ex) {
            msg.showErr(namePackage(), "java", ex);
        } finally {
        }
    }

    private boolean containsMarker(Marker m) {
        for (int i = 0; i < getMapModel().getMarkers().size(); i++) {
            if (getMapModel().getMarkers().get(i).getTitle().equals(m.getTitle())) {
                getMapModel().getMarkers().remove(i);
                return true;
            }
        }
        return false;
    }

    public void fillNavigationHistoryList() {
        navigationHistoryList.clear();
        map.clear();
        map.put("imei='" + getImei() + "'", " LIMIT 1 ");
        clearMapModel();
        gps_weaveFind = new Find();
        try {
            if (logged.getMasterId() != 0 && gps_weaveFind.byExist(map)) {
                map.clear();
                map.put("imei='" + getImei(), "' ORDER BY fecha, id");
                navigationHistoryList = gps_weaveFind.byMap(map);
            }
        } catch (Exc ex) {
            msg.showMsg(namePackage(), "system", ex.getIdError());
        } catch (SQLException ex) {
            msg.showErr(namePackage(), "sql", ex);
        } catch (Exception ex) {
            msg.showErr(namePackage(), "java", ex);
        } finally {
        }
    }

    public void toggledListener() {

        if (getToggled()) {
            lifetrackStartDate = new Date();
            clearMapModel();
            RequestContext reqCtx = RequestContext.getCurrentInstance();
            reqCtx.execute("timer.start();");
        } else {
            RequestContext reqCtx = RequestContext.getCurrentInstance();
            reqCtx.execute("timer.stop();");
        }
    }

    public List<SelectItem> getTypeList() {
        List<SelectItem> items = new ArrayList<>();

        Properties labels = new Properties();
        String idl;
        Object tempLabel;
        try {
            labels.load(gps.general.Main.class.getResourceAsStream("label_" + logged.getLoggedIdiom() + ".properties"));
            for (Enumeration idl_tipo = labels.keys(); idl_tipo.hasMoreElements();) {
                tempLabel = idl_tipo.nextElement();
                idl = tempLabel.toString();
                if (idl.contains("tipo")) {
                    items.add(new SelectItem(idl.substring(4), labels.getProperty(idl)));
                }
            }
        } catch (IOException ex) {
            msg.showErr(namePackage(), "I/O", ex);
        }
        return items;
    }

    public void onMarkerSelect(OverlaySelectEvent event) {
        setMarker((Marker) event.getOverlay());
    }

    public void clearMapModel() {
        getMapModel().getCircles().clear();
        getMapModel().getMarkers().clear();
        getMapModel().getPolygons().clear();
        getMapModel().getPolylines().clear();
        getMapModel().getRectangles().clear();
    }

    public void clear() {
        clearBeans();
        logged.setDetailId(0);
        setLat(8.932509021104444);
        setLng(-79.8275537603455);
    }

    public MapModel getEmptyModel() {
        return emptyModel;
    }

    public void selectedTempId(int tempId) {
        logged.setDetailId(tempId);
        load();
    }

    public void selectedRecordId(int tempId) {
        logged.setDetailId(tempId);
        load();
    }

    public double getLat() {
        return lat;
    }

    public void setLat(double lat) {
        this.lat = lat;
    }

    public double getLng() {
        return lng;
    }

    public void setLng(double lng) {
        this.lng = lng;
    }

    private String namePackage() {
        Package pack = this.getClass().getPackage();
        return pack.getName();
    }

    /**
     * @return the fecha_inicial
     */
    public Date getFecha_inicial() {
        return fecha_inicial;
    }

    /**
     * @param fecha_inicial the fecha_inicial to set
     */
    public void setFecha_inicial(Date fecha_inicial) {
        this.fecha_inicial = fecha_inicial;
    }

    /**
     * @return the fecha_final
     */
    public Date getFecha_final() {
        return fecha_final;
    }

    /**
     * @param fecha_final the fecha_final to set
     */
    public void setFecha_final(Date fecha_final) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(fecha_final);
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MILLISECOND, 0);
        fecha_final.setTime(cal.getTimeInMillis());
        this.fecha_final = fecha_final;
    }

    /**
     * @return the mapModel
     */
    public MapModel getMapModel() {
        return mapModel;
    }

    /**
     * @return the toggled
     */
    public Boolean getToggled() {
        return toggled;
    }

    /**
     * @param toggled the toggled to set
     */
    public void setToggled(Boolean toggled) {
        this.toggled = toggled;
    }

    /**
     * @return the filteredHistory
     */
    public List<Beans> getFilteredHistory() {
        return filteredHistory;
    }

    /**
     * @param filteredHistory the filteredHistory to set
     */
    public void setFilteredHistory(List<Beans> filteredHistory) {
        this.filteredHistory = filteredHistory;
    }

    /**
     * @return the navigationHistoryList
     */
    public List<Beans> getNavigationHistoryList() {
        return navigationHistoryList;
    }

    /**
     * @param navigationHistoryList the navigationHistoryList to set
     */
    public void setNavigationHistoryList(List<Beans> navigationHistoryList) {
        this.navigationHistoryList = navigationHistoryList;
    }

    /**
     * @return the marker
     */
    public Marker getMarker() {
        return marker;
    }

    /**
     * @param marker the marker to set
     */
    public void setMarker(Marker marker) {
        this.marker = marker;
    }
}
